package com.system.boot.company.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.system.api.SuperInterface;
import com.system.api.company.entity.po.SysCompany;
import com.system.api.rbac.entity.po.SysMenu;
import com.system.api.rbac.entity.vo.MenuTreeVo;
import com.system.boot.company.mapper.CompanyMapper;
import com.system.boot.company.service.CompanyService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.yang.common.core.exception.BaseException;
import org.yang.common.i18n.constant.I18nMessageConstant;
import org.yang.common.utils.jwt.JwtTokenAnalysisUtli;
import org.yang.database.orm.entity.BaseModel;
import org.yang.database.orm.entity.BaseQuery;
import org.yang.database.orm.entity.Options;

import java.util.*;
import java.util.stream.Collectors;

import static com.system.common.constant.MessageConstant.*;

/**
 * @author: lslands
 * @description:
 * @version：v1.0
 * @date: 2024/6/1 21:33
 */
@Service
public class CompanyServiceImpl extends ServiceImpl<CompanyMapper, SysCompany> implements CompanyService, SuperInterface<SysCompany> {

    @Override
    public void isExists(String field, String params) throws BaseException {
        if(StringUtils.isBlank(field)){
            throw new BaseException(BaseException.NULL,"field is null");
        }
        boolean existsByParams = baseMapper.getExistsByParams(field, params);
        if(existsByParams){
            throw new BaseException(BaseException.REPEAT,params);
        }
    }

    @Override
    public List<Options<Integer>> listOptions(Long companyId) throws BaseException {
        List<SysCompany> companyList = baseMapper.withList(companyId);
        if(CollectionUtil.isEmpty(companyList)){
            return new ArrayList<Options<Integer>>();
        }
        Set<Long> ids = companyList.stream().map(BaseModel::getId).collect(Collectors.toSet());
        return companyList.stream().map(menu -> {
            Long parentId = menu.getParentId();
            if (!ids.contains(parentId)) {
                ids.add(parentId);
                return recursion(parentId, companyList);
            }
            return new LinkedList<Options<Integer>>();
        }).collect(ArrayList::new, ArrayList::addAll, ArrayList::addAll);
    }
    private static List<Options<Integer>> recursion(Long parentId, List<SysCompany> list) {
        return Optional.ofNullable(list).orElse(new ArrayList<>())
                .stream().filter(menu -> menu.getParentId().equals(parentId))
                .map(x -> new Options<Integer>(x.getId().intValue(),
                        x.getName(),
                        recursion(x.getId(), list))).collect(Collectors.toList());
    }


    @Override
    public int handInsert(SysCompany record) throws BaseException {
        this.isExists("name",record.getName());
        String code = record.getCode();
        if(StringUtils.isBlank(code)){
            this.isExists("code",code);
        }
        return baseMapper.insert(record);
    }

    @Override
    public int handUpdateById(SysCompany record) throws BaseException {
        SysCompany oldResult = Optional.ofNullable(baseMapper.selectById(record.getId()))
                .orElseThrow(() -> new BaseException(BaseException.NULL));
        if (!Objects.equals(record, oldResult)) {
            String name = Optional.ofNullable(record.getName())
                    .orElseThrow(() -> new BaseException(COMPANY_NAME_EMPTY));
            if (!name.equals(oldResult.getName())) {
                this.isExists("name",record.getCode());
            }
            if(!record.getCode().equals(oldResult.getCode())) {
                this.isExists("code",record.getCode());
            }
            return baseMapper.updateById(record);
        }
        return 1;
    }

    @Override
    public int handEnabledById(Long id, Integer enabled, Integer revision) throws BaseException {
        SysCompany oldResult = Optional.ofNullable(baseMapper.selectById(id))
                .orElseThrow(()-> new BaseException(BaseException.NULL));
        if(null==enabled){
            throw new BaseException(I18nMessageConstant.VALIDATION_STATUS_EMPTY);
        }
        if(enabled.equals(oldResult.getEnabled())){
            return 1;
        }
        return baseMapper.updateById(new SysCompany(id, enabled, revision));
    }

    @Override
    public Page<SysCompany> getPage(BaseQuery query, SysCompany record) {
        Page<SysCompany> page = new Page<>(query.getCurrent(), query.getSize());
        LambdaQueryWrapper<SysCompany> wrapper = new LambdaQueryWrapper<SysCompany>()
                .like(StringUtils.isNotBlank(record.getName()), SysCompany::getName, record.getName())
                .eq(SysCompany::getParentId, record.getParentId())
                .eq(record.getEnabled()!=null,SysCompany::getEnabled,record.getEnabled())
                .orderByDesc(BaseModel::getId);
        return baseMapper.selectPage(page, wrapper);
    }

    @Override
    public int deleteOne(Long id) throws BaseException {
        if( Objects.isNull(id)){
            throw new BaseException("id cannot be null");
        }
        return baseMapper.deleteById(id);
    }

    @Override
    public int deleteBatch(Boolean delete,List<Long> ids) throws BaseException {
        if(ids.isEmpty()){
            return 0;
        }
        if(delete){
            return baseMapper.deleteBatch(ids);
        }
        return baseMapper.deleteBatchIds(ids);
    }

}
